package com.ruoyi.activity.service;

import com.ruoyi.activity.domain.Coupon;
import com.ruoyi.activity.mapper.CouponMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Arrays;

/**
 * 优惠券服务
 */
@Service
public class CouponService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private CouponMapper couponMapper;
    private static final String GRAB_SCRIPT =
            "local stockKey = KEYS[1] " +
                    "local userSetKey = KEYS[2] " +
                    "local userId = ARGV[1] " +
                    "local activityId = ARGV[2] " +

                    // 检查用户是否已抢
                    "if redis.call('sismember', userSetKey, userId) == 1 then " +
                    "   return 0 " +
                    "end " +

                    // 检查库存
                    "local stock = tonumber(redis.call('get', stockKey) or 0) " +
                    "if stock <= 0 then " +
                    "   return 0 " +
                    "end " +

                    // 扣减库存
                    "redis.call('decr', stockKey) " +

                    // 标记用户
                    "redis.call('sadd', userSetKey, userId) " +
                    "return 1";
    /**
     * 用户抢券
     * @param userId 用户ID
     * @param activityId 活动ID
     * @return 是否抢券成功
     */
    public boolean grabCoupon(Long userId, Long activityId) {
        String stockKey = "coupon:activity:" + activityId + ":stock";
        String userSetKey = "coupon:activity:" + activityId + ":users";

        Long result = redisTemplate.execute(
                new DefaultRedisScript<>(GRAB_SCRIPT, Long.class),
                Arrays.asList(stockKey, userSetKey),
                userId.toString(), activityId.toString()
        );

        if (result != null && result == 1) {
            // 异步写入数据库
            asyncSaveCoupon(userId, activityId);
            return true;
        }
        return false;
//        // 构造Redis中存储券库存的key
//        String stockKey = "coupon:activity:" + activityId + ":stock";
//        // 构造Redis中存储已抢用户集合的key
//        String userSetKey = "coupon:activity:" + activityId + ":users";
//        // 判断用户是否已抢过券
//        Boolean hasGrabbed = redisTemplate.opsForSet().isMember(userSetKey, userId);
//        if (Boolean.TRUE.equals(hasGrabbed)) {
//            // 用户已抢过，直接返回失败
//            return false;
//        }
//        // 扣减库存，原子操作防止超卖
//        Long stock = redisTemplate.opsForValue().decrement(stockKey);
//        if (stock == null || stock < 0) {
//            // 库存不足，回滚并返回失败
//            redisTemplate.opsForValue().increment(stockKey);
//            return false;
//        }
//        // 标记用户已抢，防止重复抢券
//        redisTemplate.opsForSet().add(userSetKey, userId);
//        // 新建券对象，设置用户ID、活动ID、状态
//        Coupon coupon = new Coupon();
//        coupon.setUserId(userId);
//        coupon.setActivityId(activityId);
//        coupon.setStatus(0); // 0未使用
//        // 插入券记录到数据库
//        couponMapper.insert(coupon);
//        // 抢券成功
//        return true;
    }
    @Async
    public void asyncSaveCoupon(Long userId, Long activityId) {
        Coupon coupon = new Coupon();
        coupon.setUserId(userId);
        coupon.setActivityId(activityId);
        coupon.setStatus(0);
        couponMapper.insert(coupon);
    }
} 